use std::collections::HashMap;
use std::sync::Arc;

use mysql::prelude::*;
use mysql::*;
use tokio::{runtime, sync::Mutex};


async fn query(conn: &mut PooledConn,
    keys: &Vec<String>, 
    _build_in_dbs: &Vec<String>) -> Vec<String> {
    let sql = format!(
        "select SCHEMA_NAME from information_schema.schemata where SCHEMA_NAME in ('{}')",
        keys.join("','")
    );
    let mut result = conn.query_iter(&sql).unwrap();
    // println!("sql:{}", sql);
    let mut schemas = Vec::new();
    while let Some(result_set) = result.iter() {
        for row in result_set {
            let schema_name: String = from_row(row.unwrap());
            schemas.push(schema_name);
        }
    }
    schemas
}

pub async fn query_schema(
    pool: &mysql::Pool,
    tables: &HashMap<String, Vec<String>>,
    build_in_dbs: &Vec<String>,
    page_size: usize,
) -> Vec<String> {

    let mut db_schemas: Vec<String> = Vec::new();
    // println!("{} USER {}", "-".repeat(15), "-".repeat(15));
    let mut schema_list: Vec<String> = tables.clone().into_keys().collect();
    // 启用多线程
    let schema_list_count = schema_list.len();
    let mut handles = vec![];
    let page_count = schema_list_count / page_size
        + if schema_list_count % page_size == 0 {
            0
        } else {
            1
        };
    // println!("page_count: {}", page_count);
    let page = Arc::new(Mutex::new(page_count));
    // 创建线程池
    let rt = runtime::Builder::new_multi_thread()
        .worker_threads(4)
        .enable_io()
        .enable_time()
        .build()
        .unwrap();

    loop {
        let mut lock = page.lock().await;
        let current_page: usize = lock.to_string().parse().unwrap();
        *lock -= 1;

        let mut cloned_schena_list = schema_list.clone();
        schema_list = cloned_schena_list.split_off(if cloned_schena_list.len() > page_size {
            page_size
        } else {
            cloned_schena_list.len()
        });

        let mut conn = pool.get_conn().unwrap();
        let cloned_build_in_dbs = build_in_dbs.clone();
        let handle =
            rt.spawn(async move { query(&mut conn, &cloned_schena_list, &cloned_build_in_dbs).await });
        handles.push(handle);

        if current_page <= 1 {
            break;
        }
    }

    for handle in handles {
        let mut users = handle.await.unwrap();
        db_schemas.append(&mut users);
    }
    rt.shutdown_background();

    // for owner in tables.keys() {
    //     if pos > page_size {
    //         query(conn, &keys, &mut db_users);

    //         keys.clear();
    //         values.clear();
    //         pos = 1;
    //         continue;
    //     }
    //     pos += 1;
    //     keys.push(format!("'{}'", owner.to_string()));
    // }

    // if keys.len() > 0 {
    //     query(conn, &keys, &mut db_users);
    // }
    db_schemas
}
